﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml;
using System.Xml.Linq;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;

using Centrica.Task.App.ViewModel;

namespace Centrica.Task.App
{
    /// <summary>
    /// 
    /// </summary>
    public partial class TaskViewWindow : Window
    {
        private Guid _selectedTaskID;
        private DateTime _selectedTimeFrom;

        public TaskViewWindow()
        {
            InitializeComponent();

            this._selectedTimeFrom = DateTime.Now.AddDays(-2);

            this.NewTaskCommand =
                new DelegateCommand<Object>(OnNewTaskCommand);
            this.UpdateTaskCommand =
                new DelegateCommand<Object>(OnUpdateTaskCommand);
            this.ViewForwardCommand =
                new DelegateCommand<Object>(OnViewForwardCommand);
            this.ViewBackCommand =
                new DelegateCommand<Object>(OnViewBackCommand);
            this.RemoveTaskCommand =
                new DelegateCommand<Object>(OnRemoveTaskCommand);

            App.EventAggregator
                .GetEvent<View.TaskNotificationEvent>()
                .Subscribe(OnTaskSelect, true);
            App.EventAggregator
                .GetEvent<View.TaskListEvent>()
                .Subscribe(OnTaskListChange, true);

            this.BindToListViewData();
            this.BindToCalendarViewData();
        }

        /// <summary>
        /// 
        /// </summary>
        public ICommand NewTaskCommand
        {
            get;
            private set;
        }
        public ICommand UpdateTaskCommand
        {
            get;
            private set;
        }
        public ICommand ViewForwardCommand
        {
            get;
            private set;
        }
        public ICommand ViewBackCommand 
        {
            get;
            private set;
        }
        public ICommand RemoveTaskCommand
        {
            get;
            private set;
        }

        /// <summary>
        /// 
        /// </summary>
        protected void BindToCalendarViewData()
        {
            DateTime dtFrom = this._selectedTimeFrom;

            List<TaskTimeStruct> timeData =
                TaskTimeViewModel.CreateInstance().TaskTimeData(dtFrom);

            GridView gridView = this.timeView.View as GridView;

            for (int i = 1; i < gridView.Columns.Count; ++i)
            {
                GridViewColumn c = gridView.Columns[i];
                c.Header = dtFrom.ToString("dd MMM");
                dtFrom = dtFrom.AddDays(1);
            }

            this.timeView.ItemsSource = timeData;
        }

        protected void BindToListViewData()
        {
            XmlDataProvider xmlProvider = new XmlDataProvider();
            xmlProvider.Document = TaskListViewModel.Xml;
            xmlProvider.XPath = @"/Info/Item";

            CollectionViewSource viewSource = new CollectionViewSource()
            {
                Source = xmlProvider,
            };

            viewSource.GroupDescriptions.Add(
                new PropertyGroupDescription()
                {
                    PropertyName = "@Category"
                }
            );

            this.taskListView.DataContext = viewSource;

            this.ctrl_taskStatus.ItemsSource =
                System.Enum.GetNames(typeof(Centrica.Task.Model.TaskStatus));
        }

        protected void TaskList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.taskListView.SelectedIndex > -1)
            {
                XmlElement xmlTaskItem =
                    this.taskListView.Items
                        [this.taskListView.SelectedIndex] as XmlElement;

                if (xmlTaskItem != null)
                {
                    Centrica.Task.Model.Task taskItem =
                        Model.TaskModelFactoryProvider.StaticInstance
                        .Provider.Find(
                            t => (t.ID.ToString() == xmlTaskItem.Attributes["__ID"].Value));

                    App.EventAggregator.GetEvent<View
                        .TaskNotificationEvent>()
                        .Publish(taskItem);
                }
            }
        }

        private void OnTaskListChange(Centrica.Task.Model.ITaskProvider provider)
        {
            this.BindToListViewData();
            this.BindToCalendarViewData();
        }

        private void OnTaskSelect(Centrica.Task.Model.Task taskObj)
        {
            this.ctrl_taskDescription.Text = taskObj.Description;
            this.ctrl_taskName.Text = taskObj.Name;
            this.ctrl_taskOwner.Text = taskObj.Owner;
            this.ctrl_taskStatus.SelectedItem = taskObj.Status.ToString();
            this.ctrl_taskStartDate.Text = taskObj.StartDate.ToString(@"dd/MM/yyyy");
            this.ctrl_taskEndDate.Text = taskObj.FinishDate.ToString(@"dd/MM/yyyy");
            this._selectedTaskID = taskObj.ID;
        }

        /// <summary>
        /// Command Handlers
        /// </summary>
        private Centrica.Task.Model.Task CreateTaskFromUI()
        {
            Centrica.Task.Model.Task task =
                Centrica.Task.App.Model.TaskProxy.CreateInstance();

            task.Description = this.ctrl_taskDescription.Text;
            task.Name = this.ctrl_taskName.Text;
            task.Owner = this.ctrl_taskOwner.Text;
            task.Status = (Centrica.Task.Model.TaskStatus)System.Enum.Parse(
                typeof(Centrica.Task.Model.TaskStatus),
                this.ctrl_taskStatus.SelectedItem.ToString());
            task.StartDate = DateTime.Parse(this.ctrl_taskStartDate.Text);
            task.FinishDate = DateTime.Parse(this.ctrl_taskEndDate.Text);

            return task;
        }

        private void OnNewTaskCommand(Object sender)
        {
            Centrica.Task.Model.Task task = this.CreateTaskFromUI();

            App.EventAggregator.GetEvent<View
                .TaskNewEvent>()
                .Publish(task);
        }

        private void OnUpdateTaskCommand(Object sender)
        {
            Centrica.Task.Model.Task task = this.CreateTaskFromUI();

            task.ID = this._selectedTaskID;

            App.EventAggregator.GetEvent<View
                .TaskUpdateEvent>()
                .Publish(task);
        }

        private void OnViewForwardCommand(Object sender)
        {
            this._selectedTimeFrom = this._selectedTimeFrom.AddDays(4);
            this.BindToCalendarViewData();
        }

        private void OnViewBackCommand(Object sender)
        {
            this._selectedTimeFrom = this._selectedTimeFrom.AddDays(-4);
            this.BindToCalendarViewData();
        }

        private void OnRemoveTaskCommand(Object sender)
        {
            Centrica.Task.Model.Task task = this.CreateTaskFromUI();

            task.ID = this._selectedTaskID;

            App.EventAggregator.GetEvent<View
                .TaskRemoveEvent>()
                .Publish(task);
        }

    }
}
